<?php
/**
 * Created by PhpStorm.
 * User: 王柯 <wangke.email@foxmail.com>
 * Date: 2018\4\7 0007
 * Time: 14:53
 */
namespace alipay;
use app\common\lib\exception\ApiException;

/**
 * 阿里支付所有服务类方法
 * Class AlipayTradeService
 * @package alipay
 */
class AlipayTradeService{
    //支付宝网关地址
    public $gateway_url = "https://openapi.alipay.com/gateway.do";

    //支付宝公钥
    public $alipay_public_key;

    //商户私钥
    public $private_key;

    //应用id
    public $app_id;

    //编码格式
    public $charset = "UTF-8";

    public $token = NULL;

    //返回数据格式
    public $format = "json";

    //签名方式
    public $sign_type = "RSA";

    //异步通知地址
    public $notify_url;

    //同步跳转
    public $return_url;

    /**
     * 构造参数 constructor.
     * @throws ApiException
     */
    public function __construct(){
        $this->gateway_url = config('alipay.gatewayUrl');
        $this->app_id = config('alipay.app_id');
        $this->private_key = config('alipay.merchant_private_key');
        $this->alipay_public_key = config('alipay.alipay_public_key');
        $this->charset = config('alipay.charset');
        $this->sign_type = config('alipay.sign_type');
        $this->notify_url = config('alipay.notify_url');
        $this->return_url = config('alipay.return_url');

        if(empty($this->app_id)||trim($this->app_id) == ''){
            throw new ApiException('appid should not be NULL!');
        }
        
        if(empty($this->private_key)||trim($this->private_key) == ''){
            throw new ApiException('private_key should not be NULL!');
        }
        
        if(empty($this->alipay_public_key)||trim($this->alipay_public_key) == ''){
            throw new ApiException('alipay_public_key should not be NULL!');
        }
        
        if(empty($this->charset)||trim($this->charset) == ''){
            throw new ApiException('charset should not be NULL!');
        }
        
        if(empty($this->gateway_url)||trim($this->gateway_url) == ''){
            throw new ApiException('gateway_url should not be NULL!');
        }
    }

    /**
     * 阿里wap支付
     * @param array $biz_content 订单组成参数 *必传
     * @author 王柯 <wangke.email@foxmail.com>
     * @return string
     */
    public function WapPay($biz_content)
    {
        require_once('aop/AopClient.php');
        require_once('aop/request/AlipayTradeWapPayRequest.php');
        $aop = new \AopClient();

        //支付宝网关
        $aop->gatewayUrl = $this->gateway_url;

        //应用ID APPID
        $aop->appId = $this->app_id;

        //商户私钥
        $aop->rsaPrivateKey = $this->private_key;
        $aop->format = "json";

        //编码格式
        $aop->charset = $this->charset;

        //签名方式
        $aop->signType = $this->sign_type;

        //支付宝公钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;

        //参数效验
        self::checkParams($biz_content);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.wap.pay
        $request = new \AlipayTradeAppPayRequest();

        //支付宝异步回调
        $request->setNotifyUrl($this->notify_url);

        //同步通知
        $request->setReturnUrl($this->return_url);

        //组装参数
        $request->setBizContent(json_encode($biz_content));

        //页面提交
        $response = $aop->pageExecute($request);
        return $response;
    }

    /**
     * 阿里app支付
     * @param array $biz_content 订单组成参数 *必传
     * @author 王柯 <wangke.email@foxmail.com>
     * @return string
     */
    public function AppPay($biz_content)
    {
        require_once('aop/AopClient.php');
        require_once('aop/request/AlipayTradeAppPayRequest.php');
        $aop = new \AopClient();

        //支付宝网关
        $aop->gatewayUrl = $this->gateway_url;

        //应用ID APPID
        $aop->appId = $this->app_id;

        //商户私钥
        $aop->rsaPrivateKey = $this->private_key;
        $aop->format = "json";

        //编码格式
        $aop->charset = $this->charset;

        //签名方式
        $aop->signType = $this->sign_type;

        //支付宝公钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;

        //参数效验
        self::checkParams($biz_content);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        $request = new \AlipayTradeAppPayRequest();

        //支付宝异步回调
        $request->setNotifyUrl($this->notify_url);

        //同步通知
        $request->setReturnUrl($this->return_url);

        //组装参数
        $request->setBizContent(json_encode($biz_content));

        //SDK字符串
        $response = $aop->sdkExecute($request);
        return $response;
    }

    /**
     * 阿里交易关闭
     * @param array $biz_content 订单组成参数 *必传
     * @author 王柯 <wangke.email@foxmail.com>
     * @return string
     */
    public function Close($biz_content)
    {
        require_once('aop/AopClient.php');
        require_once('aop/request/AlipayTradeCloseRequest.php');
        $aop = new \AopClient();

        //支付宝网关
        $aop->gatewayUrl = $this->gateway_url;

        //应用ID APPID
        $aop->appId = $this->app_id;

        //商户私钥
        $aop->rsaPrivateKey = $this->private_key;
        $aop->format = "json";

        //编码格式
        $aop->charset = $this->charset;

        //签名方式
        $aop->signType = $this->sign_type;

        //支付宝公钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.wap.pay
        $request = new \AlipayTradeCloseRequest();

        //支付宝异步回调
        $request->setNotifyUrl($this->notify_url);

        //同步通知
        $request->setReturnUrl($this->return_url);

        //组装参数
        $request->setBizContent(json_encode($biz_content));

        $result = $aop->execute ( $request);

        return $result->alipay_trade_close_response;
        /*$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";

        $resultCode = $result->$responseNode->code;

        if(!empty($resultCode) && $resultCode == 10000){
            return $result;
        } else {
            return '交易关闭失败！';
        }*/
    }

    /**
     * 阿里交易查询
     * @param array $biz_content 订单组成参数 *必传
     * @author 王柯 <wangke.email@foxmail.com>
     * @return string
     */
    public function Query($biz_content)
    {
        require_once('aop/AopClient.php');
        require_once('aop/request/AlipayTradeQueryRequest.php');
        $aop = new \AopClient();

        //支付宝网关
        $aop->gatewayUrl = $this->gateway_url;

        //应用ID APPID
        $aop->appId = $this->app_id;

        //商户私钥
        $aop->rsaPrivateKey = $this->private_key;
        $aop->format = "json";

        //编码格式
        $aop->charset = $this->charset;

        //签名方式
        $aop->signType = $this->sign_type;

        //支付宝公钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.wap.pay
        $request = new \AlipayTradeQueryRequest();

        //支付宝异步回调
        $request->setNotifyUrl($this->notify_url);

        //同步通知
        $request->setReturnUrl($this->return_url);

        //组装参数
        $request->setBizContent(json_encode($biz_content));

        $result = $aop->execute($request);

        return $result->alipay_trade_query_response;
        /*$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";

        $resultCode = $result->$responseNode->code;

        if(!empty($resultCode) && $resultCode == 10000){
            return $result;
        } else {
            return '交易查询失败！';
        }*/
    }

    /**
     * 异步通知验签
     * @param string $params 参数
     * @author 王柯 <wangke.email@foxmail.com>
     * @return bool 是否通过
     */
    public function rsaCheck($params, $signType)
    {
        require_once('aop/AopClient.php');

        $aop = new \AopClient();

        //支付宝网关
        $aop->gatewayUrl = $this->gateway_url;

        //应用ID APPID
        $aop->appId = $this->app_id;

        //商户私钥
        $aop->rsaPrivateKey = $this->private_key;
        $aop->format = "json";

        //编码格式
        $aop->charset = $this->charset;

        //签名方式
        $aop->signType = $this->sign_type;

        //支付宝公钥
        $aop->alipayrsaPublicKey = $this->alipay_public_key;
        return $aop->rsaCheckV1($params, null, $signType);
    }

    /**
     * 参数效验
     * @param array $params 数组参数
     * @param string $params['body'] 交易描述 *必传
     * @param string $params['subject'] 标题 *必传
     * @param string $params['out_trade_no'] 订单编号 *必传
     * @param float $params['total_amount'] 交易金额 *必传
     * @author 王柯 <wangke.email@foxmail.com>
     * @return void
     */
    private static function checkParams($params)
    {
        if (empty(trim($params['body']))) {
            throw new ApiException('商品描述(body)必填',404);
        }

        if (empty(trim($params['subject']))) {
            throw new ApiException('商品标题(subject)必填',404);
        }

        if (empty(trim($params['out_trade_no']))) {
            throw new ApiException('商户订单号(out_trade_no)必填',404);
        }

        if (floatval(trim($params['total_amount'])) <= 0) {
            throw new ApiException('订单金额(total_amount)为大于0的数',401);
        }
    }
}
